/**
 * 菜单数据
 */
import { defineStore } from 'pinia'
import { ref } from "vue"
import router from "@/router/index.js";
import { menus as mockMenus } from '@/mock/index.js'
import { useAdminUserStore } from "@/store/adminUser"
import { allMenus } from '@/api/system/sysUser.js'

export const useMenuStore = defineStore("menuStore", () => {
    const adminUserStore = useAdminUserStore()

    //菜单集合
    const menus = ref([])

    //模块菜单集合
    const moduleMenus = ref([])

    //激活的模块菜单索引
    const activeModuleMenuIndex = ref(0)

    // 菜单折叠状态
    const collapseStatus = ref(false)

    //侧边栏菜单集合
    const sidebarMenus = ref([])

    //侧边栏激活菜单
    const activeMenu = ref("/index")

    //导航菜单集合
    const navMenus = ref([])

    //激活的导航菜单索引
    const activeNavMenuIndex = ref(-1)

    //读取所有组件
    const modules = import.meta.glob('../pages/**/*.vue')

    //刷新标识
    const refreshKey = ref(Date.now())

    //初始化状态
    const initStatus = ref(false)

    let resolveMenuInitialized;
    const menuInitializedPromise = new Promise((resolve) => {
        resolveMenuInitialized = resolve
    })

    //设置activeModuleMenuIndex
    const setActiveModuleMenuIndex = (index) => {
        activeModuleMenuIndex.value = index
    }

    //设置activeMenu
    const setActiveMenu = (index) => {
        activeMenu.value = index
    }

    //设置navMenus
    const setNavMenus = (data) => {
        navMenus.value = data
    }

    //退出后的销毁工作
    const destroy = () => {
        moduleMenus.value = []
        setActiveMenu('/index')
        setActiveModuleMenuIndex(0)
        setNavMenus([])
        collapseStatus.value = false
        initStatus.value = false
    }

    /**
     * 更新激活的菜单项
     * @param index
     */
    const updateActiveMenu = (index) => {
        setActiveMenu(index)
        toRoute(index)
    }

    /**
     * 更新菜单折叠状态
     * @param status
     */
    const updateMenuCollapseStatus = (status) => {
        collapseStatus.value = status
    }

    // 模拟远程请求函数
    function mockApiRequest(data, delay = 1000) {
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve(mockMenus); // 模拟返回的数据
            }, delay);
        });
    }

    /**
     * 初始化菜单、路由和按钮权限
     */
    const init = async () => {
        if (!initStatus.value) {
            if (import.meta.env.VITE_APP_MODE === 'static') {
                menus.value = mockMenus
            } else {
                if (adminUserStore.tokenInfo) {
                    const resp = await allMenus()
                    menus.value = resp.data
                }
            }
            registerDynamicRoute(menus.value)
            initSidebarMenu(menus.value)
            initStatus.value = true
            resolveMenuInitialized()        //Promise状态由pending转成fulfilled
        }
    }

    /**
     * 初始化侧边菜单栏
     * @param menuData 菜单配置集合
     */
    const initSidebarMenu = (menuData) => {
        if (menuData && menuData.length > 0) {
            menuData.forEach(item => {
                moduleMenus.value.push(item)
            })

            sidebarMenus.value = [...menuData[0].children]
        }
    }

    /**
     * 更新菜单集合
     * @param moduleMenuIndex
     */
    const updateSidebarMenu = (moduleMenuIndex) => {
        sidebarMenus.value.splice(0, sidebarMenus.value.length)
        sidebarMenus.value = [...menus.value[moduleMenuIndex].children]
    }

    /**
     * 注册动态路由
     * @param menuData 菜单配置集合
     */
    const registerDynamicRoute = (menuData) => {
        let dynamicRoutes = getRoutesByMenus(menuData)
        if (dynamicRoutes.length > 0) {
            const childrenRoutes = dynamicRoutes.map(dynamicRoute => {
                dynamicRoute.component = modules[(`../pages${dynamicRoute.component}.vue`)]
                return dynamicRoute
            })

            //内置空白页
            childrenRoutes.push({path: "/empty", name: "Empty", component: modules[(`../pages/empty.vue`)]})

            let routeConfig = {path: "/", name: "AdminIndex", component: modules[(`../pages/AdminIndex.vue`)], children: childrenRoutes};
            router.addRoute(routeConfig)
        }
    }

    //通过菜单项获取动态路由配置
    const getRoutesByMenus = (menus) => {
        let routes = []
        if (menus.length > 0) {
            menus.forEach(menuItem => {
                if (menuItem.type === 2) {
                    routes.push(menuItem)
                }
                if (menuItem.children && menuItem.children.length > 0) {
                    let subRoutes = getRoutesByMenus(menuItem.children)
                    if (subRoutes.length > 0) {
                        routes.push(...subRoutes)
                    }
                }
            })
        }

        return routes
    }

    //通过菜单获取按钮级别配置
    const getButtonPermissionByMenus = () => {

    }

    /**
     * 添加导航菜单项
     * @param menuIndex 激活菜单索引
     */
    const addNavMenu = (menuIndex) => {
        let activeMenu = findMenuByPath(menuIndex, menus.value)
        if (activeMenu != null) {
            if (!hasNavMenu(activeMenu)) {
                navMenus.value.push(activeMenu)
            }
            let topNode = findTopNode(menus.value, menuIndex)
            if (topNode != null) {
                let moduleMenuIndex = -1
                for (let i = 0; i < menus.value.length; i++) {
                    let menuItem = menus.value[i]
                    if (menuItem.path === topNode.path) {
                        moduleMenuIndex = i
                        break
                    }
                }

                if (moduleMenuIndex !== -1) {
                    activeMenu.meta.moduleMenuIndex = moduleMenuIndex
                    activeModuleMenuIndex.value = moduleMenuIndex
                }
            }

            activeNavMenuIndex.value = activeMenu.id
        }
    }

    /**
     * 查找顶级节点
     * @param tree
     * @param targetNodePath
     */
    function findTopNode(tree, targetNodePath) {
        let topNode = null
        if (tree && tree.length > 0) {
            for (let topItem of tree) {
                let topItemArr = [topItem]
                if (topItem.children) {
                    topItemArr.push(...treeToFlat(topItem.children))
                }

                for (let item of topItemArr) {
                    if (item.path === targetNodePath) {
                        topNode = topItemArr[0]
                        break
                    }
                }

                if (topNode != null) {
                    break
                }
            }
        }

        return topNode
    }

    /**
     * 树形结构转扁平结构
     * @param tree
     */
    function treeToFlat(tree) {
        let flatArr = []
        if (tree && tree.length > 0) {
            for (let treeItem of tree) {
                flatArr.push(treeItem)
                if (treeItem.children && treeItem.children.length > 0) {
                    let subFlatArr = treeToFlat(treeItem.children)
                    flatArr.push(...subFlatArr)
                }
            }
        }
        return flatArr
    }

    /**
     * 删除导航菜单项目
     * @param navMenu
     */
    const deleteNavMenu = (navMenu) => {
        let index = navMenus.value.reduce((init, next, currentIndex) => {
            if (next.id === navMenu.id) {
                init = currentIndex
            }
            return init
        }, -1)
        navMenus.value.splice(index, 1)
        updateActiveNavMenu(navMenus.value[index-1])
    }

    /**
     * 删除其他标签页
     */
    const deleteOtherNavMenus = () => {
        if (activeNavMenuIndex.value > -1) {
            let currentNavMenu = null
            for (let navMenuItem of navMenus.value) {
                if (navMenuItem.id === activeNavMenuIndex.value) {
                    currentNavMenu = {...navMenuItem}
                    break
                }
            }
            if (currentNavMenu !== null) {
                navMenus.value.splice(0, navMenus.value.length)
                navMenus.value.push(currentNavMenu)
            }
        }
    }

    /**
     * 删除所有标签页
     */
    const deleteAllNavMenus = () => {
        navMenus.value.splice(0, navMenus.value.length)
        activeMenu.value = ''
        toRoute("/empty")
    }

    /**
     * 更新激活的导航菜单索引
     * @param navMenu 导航菜单对象
     */
    const updateActiveNavMenu = (navMenu) => {
        activeNavMenuIndex.value = navMenu.id
        if (navMenu.meta.moduleMenuIndex !== activeModuleMenuIndex.value) {
            activeModuleMenuIndex.value = navMenu.meta.moduleMenuIndex
            sidebarMenus.value = [...menus.value[activeModuleMenuIndex.value].children]
        }
        updateActiveMenu(navMenu.path)
    }

    /**
     * 通过path查找指定菜单项目
     * @param menuPath 待查找的菜单地址
     * @param sidebarMenu 侧边栏菜单
     */
    const findMenuByPath = (menuPath, sidebarMenu) => {
        let menu = null
        sidebarMenu.forEach(menuItem => {
            if (menuItem.path === menuPath) {
                menu = menuItem
            } else {
                if (menuItem.children instanceof Array && menuItem.children.length > 0) {
                    let resMenu = findMenuByPath(menuPath, menuItem.children)
                    if (resMenu != null) {
                        menu = resMenu
                    }
                }
            }
        })
        return menu
    }

    /**
     * 判断是否存在导航菜单项目
     * @param menu
     * @returns {boolean}
     */
    const hasNavMenu = (menu) => {
        let has = false
        navMenus.value.forEach(navMenuItem => {
            if (navMenuItem.id === menu.id) {
                has = true
            }
        })

        return has
    }

    /**
     * 跳转路由
     * @param path
     */
    const toRoute = (path) => {
        router.push(path)
    }

    return {
        collapseStatus,
        refreshKey,
        sidebarMenus,
        activeMenu,
        moduleMenus,
        activeModuleMenuIndex,
        navMenus,
        activeNavMenuIndex,
        menuInitializedPromise,
        initStatus,
        updateMenuCollapseStatus,
        init,
        updateActiveMenu,
        updateSidebarMenu,
        addNavMenu,
        deleteNavMenu,
        deleteOtherNavMenus,
        deleteAllNavMenus,
        updateActiveNavMenu,
        destroy
    }
})
